<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class App extends CI_Controller {
	
	// 目录配置 /application/config/common.php
	private $_path = array();
	
	// 通知跳转页面
	static private $_notice = 'notice';
	
	// 操作类型
	static private $_type = array(
		'DELETE' => '删除',
		'UPDATE' => '更新',
		'READ' => '读取',
		'CREATE' => '创建',
		'SHOW' => '创建表单',
		'SUBMIT'=>'提交表单'
	);
	// showForm 表单提示的title 相当于 submitForm 中的 $act
	static private $_act = array(
		'import_app_file' => '导入应用文件',									
		'update_app_file' => "更新应用文件",
		'add_app_file'=> "添加应用文件",
		'delete_app_file'=>"删除应用文件",
		
		'delete_app' => "删除整个应用",
		'delete_app_edition'=>'删除应用版本',
		'add_app_version'=>"添加应用版本",
		
		'delete_applib'=>"删除策略",
		'add_applib_version' => '添加策略的应用版本',
		'delete_applib_version' => '删除策略的应用版本',
		
		'deploy_applib_version' => '部署应用版本',		
	);
	
	public function __construct()
	{
		parent::__construct();		
		$this->_path = config_item("path");
	}		

	// 应用管理、策略管理
	public function index()
	{
		$data = array();
		$page = $this->uri->segment(3, 'app');
		$page = (is_null($page)) ? 'app' : $page;		
		
		$data['page'] = $page;
		$data['add_app'] = site_url('app/addApp/'.$page);		
		$data['title'] = ($page=='app') ? '应用' : '策略';		
		$data['list'] = ($data['page'] == 'app') ? $this->getApp() : $this->getStrategy();
		
		$this->load->view('app', $data);
	}		
	// 版本管理
	public function version()
	{
		$data = array();
		$page = $this->uri->segment(3);
		$data['page'] = $page;		
		
		if ($page == 'app')
		{			
			$id = $this->uri->segment(4); // 版本的id
			$app_id = $this->uri->segment(5);
			$edition = $this->uri->segment(6);			
			$path = $this->uri->segment(7);
			
			$data['version'] = $edition;			
			$data['app_id'] = $app_id;
			$data['id'] = $id;
			
			$data['add_link'] = site_url('app/showForm/add_app_file/'.$app_id . '/' . $edition . '/' . $id . '/' . $path);
			$data['import_link'] = site_url('app/showForm/import_app_file/'.$app_id . '/' . $edition . '/' . $id . '/' . $path);
			$data['delete_link'] = site_url('app/showForm/delete_app_edition/'.$app_id . '/' . $edition . '/' . $id . '/' . $path);
			
			$filelist = $this->getVersionFiles($app_id, $edition, $id, urldecode($path));	
			if ($filelist)
			{
				$data['list'] = $filelist['list'];
				$data['top'] = $filelist['top'];
				$data['back'] = $filelist['back'];
				$data['path'] = str_replace(".", "/", $path);	
			}			
		}
		else
		{
			$applib_id = $this->uri->segment(4);						
			$query = $this->db->query("SELECT * FROM applibraries_tbl WHERE applib_id = $applib_id");
			$lib = $query->row_array();
			$data['applib_title'] = $lib['applib_title'];		
			$data['applib_id'] = $applib_id;
			$data['link'] = site_url('app/showForm/add_applib_version/'.$applib_id);			
			$data['list'] = $this->getStrategyList($applib_id);		
		}

		$this->load->view('version', $data);		
	}
	
	// 获取应用版本下的所有文件
	private function getVersionFiles($app_id, $edition_id, $id, $path)
	{
		$link_str = sprintf("app/version/app/%d/%s/%s/",$id, $app_id, $edition_id);
		$base = sprintf($this->_path['local_version']."%s/%s/", $app_id, $edition_id);		
		$dir_path = "";		
		
		if ($path)
		{			
			if (strpos($path, ".") > 0)
			{
				$dir_path = $base.str_replace('.', '/', $path);					
				$back_link = site_url($link_str.substr($path, 0, strrpos($path, ".")));
			}
			else
			{	
				$dir_path = $base.$path;				
				$back_link = site_url($link_str);
			}		
		}
		else
		{
			$dir_path = $base;
			$back_link = site_url($link_str);
		}
		
		if (!file_exists($dir_path)) { return false; }	
		
		$this->load->helper('directory');		
					
		$files = directory_map($dir_path, 1);		
		$list = array('file'=>array(), 'dir'=>array());
		$link = "/app/showForm/%s/%s/%s/%d/%d";		
		foreach($files as $filename)
		{			
			$item = array();
			$item['file_name'] = $filename;
			
			if($filename[strlen($filename) - 1] == '/')
			{				
				$segment = ($path) ? $path. "." . $filename : $filename;
				$item['link'] = site_url($link_str. $segment);
				$item['type'] = 'dir';
				$list['dir'][] = $item;
			}
			else
			{			
				$file_path = get_file_path($path, $filename);				
				// @todo 一次获取				
				$sql = sprintf("SELECT file_id, file_name, file_version, file_size FROM appfiles_tbl WHERE app_id = '%s' AND edition_id = '%s' AND file_name = '%s' AND file_path = '%s'", $app_id, $edition_id, $filename, $file_path);
				$query = $this->db->query($sql);
				$entity = $query->row_array();
				
				$entity['file_path'] = $file_path;				
 			    $item['delete'] = site_url(sprintf($link, "delete_app_file", $app_id, $edition_id, $id, $entity['file_id']));
 			    $item['update'] = site_url(sprintf($link, "update_app_file", $app_id, $edition_id, $id, $entity['file_id']));
				
				$item['type'] = 'file';				
				$item = array_merge($item, $entity);
				$list['file'][] = $item;
			}						
		}
		// 分组排序		
		if (!empty($list['file'])) { ksort($list['file']);}
		if (!empty($list['dir'])) { ksort($list['dir']);}		
		$newlist = array_merge($list['file'], $list['dir']);
					
		return array('list'=>$newlist, 'top'=>site_url($link_str), 'back'=>$back_link);
	}
	
	// 获取策略的应用列表
	private function getStrategyList($id)
	{
		$data = array();
		$query = $this->db->query("SELECT a.*,b.id, b.edition_ver as top_ver FROM applibraryentries_tbl a 
					LEFT JOIN appeditions_tbl b 
					ON a.app_id = b.app_id AND a.edition_id = b.edition_id
						WHERE applibrary_id = $id");
		$applib = array();
		if ($query->num_rows() > 0)
		{
			foreach($query->result_array() as $row) 
			{										
				$row['app_files'] = site_url(sprintf("app/version/app/%d/%s/%s/%s", $row['id'], $row['app_id'], $row['edition_id'], 'show'));
				//$this->log(self::$_type['READ'],  "读取策略applibrary_id:{$id}下的所有应用版本");
				if($row['state']==0) 
				{
					$row['delete']=site_url(sprintf("app/showForm/delete_applib_version/".$id.'/'.$row['applibentry_id']));						}
				$row['deploy'] = site_url(sprintf("app/showForm/deploy_applib_version/".$id.'/'.$row['applibentry_id']));	
				$data[] = $row;
			}
		}
		return $data;
	}
	
	// 获取文件压缩的正确路径
	private static function getCorrectPath($path, $filename)
	{
		return (empty($path)) ? $filename : trim($path, '/').'/'.$filename;	
	}
	
	// 提交表单的处理
	public function submitForm()
	{		
		$act = $this->input->post('act');				
		$this->log(self::$_type['SUBMIT'], "表单提交处理操作 ".self::$_act[$act]);
		switch($act)
		{
			// 添加应用文件 codeigniter::upload 貌似只支持单个文件上传，我们允许上传多个文件，并不做类型及最大值验证。采用系统默认值。
			case "add_app_file":			
			$msg = "上传结果: <br />";
			if (!empty($_FILES)) 
			{
				$path_num = 1;
				foreach($_FILES as $name => $file)
				{
					if($file['error'] == 0)
					{
						$file_upload_path = $this->_path['local_upload'].$file['name'];
						if(move_uploaded_file($file['tmp_name'], $file_upload_path))
						{	
							$path = self::getCorrectPath($this->input->post("path".$path_num), $file['name']);
							$msg .= $path."  <span style='color:green;'>上传成功</span><br/>";
							$this->insertAppFile($file_upload_path, $file, $path);							
							//上传成功后删除文件(保存文件在数据库)
							unlink($file_upload_path);
						}
					}
					else
					{						
						$msg .= sprintf("%s %s/%s <span style='color:red';>文件上传失败，错误代码:%d</span>", $name,$this->input->post("path".$path_num), $file['name'], $file['error']);						
					}
					$path_num++;		
				}	
				$this->load->view('notice', array('msg'=>$msg, 'title'=>"上传文件"));
			}	
			else
			{
				$this->load->view('notice', array('msg'=>"上传文件为空", 'title'=>"上传文件"));
			}	
			
			break;	
			// 更新应用文件
			case "update_app_file":
			
			if(isset($_FILES['file1']) && $_FILES['file1']['error'] == 0)
			{
				$file_upload_path = './public/uploads/'.$_FILES['file1']['name'];
				if(move_uploaded_file($_FILES['file1']['tmp_name'], $file_upload_path))
				{			
					$this->load->view('notice',$this->updateAppFile($file_upload_path, $_FILES['file1']));
				}
			}
			else
			{
				$this->load->view('notice', array('title'=>'上传文件', 'msg'=>'文件提交失败'));		
			}
			break;
			// 删除应用文件
			case "delete_app_file":
				$command = $this->input->post('command');
				if ($command == 'YES') 
				{					
					$this->deleteAppFile($this->input->post('file_id'));	
					$this->updateVersion($this->input->post('id'));
					$this->load->view('notice', array('title'=>'删除文件', 'msg'=>'文件删除成功'));		
				} 
				else 
				{
					$this->load->view('notice', array('title'=>'删除文件', 'msg'=>'文件删除失败'));		
				}			
			break;
			// 添加应用版本
			case "add_app_version":
				// 不能重名，不能为空
				$app_id = $this->input->post('app_id');	
				$version_id = $this->input->post('version_id');	
				
				if (!$version_id || $this->isVersionExists($app_id, $version_id))
				{
					$this->load->view('notice', array('title'=>'创建新版本', 'msg'=>"版本[{$version_id}]已存在或版本为空，请检查。"));			
				}
				else
				{
					$insert = array(
						'app_id' => $app_id,
						'edition_id' => $version_id,
						'edition_ver' => 1,
						'edition_intro' => 'nothing',
						'add_time' => date("Y-m-d H:i:s")						
					);	
					$this->db->insert('appeditions_tbl', $insert);					
					// 创建版本目录
					mkdir(get_app_version_dir($app_id, $version_id));
					
					$this->log(self::$_type['CREATE'], "为应用{$app_id}添加一个新版本{$version_id}", $app_id);
					$this->load->view('notice', array('title'=>'创建新版本', 'msg'=>'创建成功'));
				}
				
			break;
			// 删除策略
			case "delete_applib":
				$command = $this->input->post('command');
				if ($command == 'YES') 
				{
					// 策略对应的应用版本文件数据一并删除，不能删除已部署的应用
					$applib_id = $this->input->post('applib_id');						
					$sql = "SELECT a.applib_title, b.* FROM applibraries_tbl a LEFT JOIN applibraryentries_tbl b 
ON a.applib_id = b.applibrary_id WHERE a.applib_id = $applib_id";
					$query = $this->db->query($sql);
					$count = 0;
					$msg = "删除结果： <br />";
										
					if (($size = $query->num_rows()) > 0)
					{
						foreach($query->result_array() as $row)
						{
							if ($row['state'] == 0) 
							{
								++$count;
								$this->deleteAppLibVersion($applib_id, $row);
								$msg .= sprintf("［%s］删除策略［%s］应用版本。<br />", $row['applib_title'], $row['app_id']);	
							}
							else
							{
								$msg .= sprintf("<span style='color: red;'>［%s］策略［%s］应用版本已部署，无法删除。</span><br />",$row['applib_title'], $row['app_id']);	
							}							
						}						
						// 如果当前应用全部没有部署，全部删除，最后删除这个策略
						// @todo 如果需要删除已部署的应用呢？
						if ($size == $count)
						{
							$this->deleteAppLib($applib_id);	
							$this->load->view('notice', array('title'=>'删除策略', 'msg'=>$msg));	
						}
						else
						{
							// 统计删除了的应用版本，不删除这个策略
							$this->load->view('notice', array('title'=>'删除策略', 'msg'=>$msg));
						}						
					}
					else
					{
						// 当前策略没有部署或添加任何应用，直接删除。
						$this->deleteAppLib($applib_id);
						$this->load->view('notice', array('title'=>'删除策略', 'msg'=>'删除策略成功'));		
					}														
				} 
				else 
				{
					$this->load->view('notice', array('title'=>'删除策略', 'msg'=>'删除策略失败'));		
				}				
			break;
			
			case "delete_applib_version":
			$command = $this->input->post('command');
			if ($command == 'YES') 
			{
				$applib_id = $this->input->post("applib_id");
				$applibentry_id = $this->input->post("applibentry_id");
				
				$query = $this->db->query("SELECT * FROM applibraryentries_tbl WHERE applibrary_id = $applib_id AND applibentry_id = $applibentry_id");
				$applib = $query->row_array();
								
				$this->deleteAppLibVersion($applib_id, $applib);								
				$this->load->view('notice', array('title'=>'删除策略应用版本', 'msg'=>"删除策略{$applib['applibentry_id']}应用{$applib['app_id']}版本{$applib['edition_id']}成功"));													
			} 
			else 
			{
				$this->load->view('notice', array('title'=>'删除策略应用版本', 'msg'=>'删除策略应用版本失败'));		
			}
			break;
			
			// 添加应用版本
			case "add_applib_version":
			/*
Array
(
    [act] => add_applib_version
    [applib_id] => 5
    [app_id] => anhei
    [anhei] => ffffs_1
)
			*/							
			$app_id = $this->input->post('app_id');	
			$applib_id = $this->input->post('applib_id');
			$edition = $this->input->post($app_id);
			
			// 判断是否选择了应用及应用版本
			if (!$app_id || !$edition)
			{
				$this->load->view('notice', array('title'=>'添加应用版本', 'msg'=>"请选择一个应用和版本文件"));
			}
			else
			{		
				list($edition_id, $edition_ver) = explode("_", $edition);				
				$app = array(
					'app_id'=>$app_id,
					'edition_id'=>$edition_id,
					'edition_ver'=>$edition_ver
				);									
				$msg = "";				
				if ($this->hasAppFiles($app)) 
				{
					$files = $this->insertAppLib($applib_id, $app);
					$filesize = count($files);
					$msg .= "<span style='color: green;'>".$app['app_id']."[".$app['edition_id']."] 一共添加了 $filesize 个文件</span><br />";
					if ($filesize > 0) {
						$msg .= implode("<br />", $files);
					}
				} 
				else 
				{
					$msg .= $app['app_id']."[".$app['edition_id']."] 没有文件<br />";
				}																					
				$this->load->view('notice', array('title'=>'添加应用版本', 'msg'=>$msg));									
			}								
			break;
						
			case 'import_app_file':	// 导入应用压缩文件
			case 'delete_app_edition':		// 删除应用版本
				$app_id = $this->input->post('app_id');	
				$edition_id = $this->input->post('edition_id');	
				$id = $this->input->post('id'); // 版本的id				
				$this->load->library("AppManage", array('id'=>$id, 'app_id'=>$app_id, 'edition_id'=>$edition_id));				
				if ($act == 'import_app_file') 
				{
					$this->load->view('notice', array('title'=>'导入应用版本', 'msg'=>$this->appmanage->importApp()));
				} 
				else if ($act == 'delete_app_edition')										
				{
					$command = $this->input->post('command');
					if ($command == 'YES') 
					{											
						$this->load->view('notice', array('title'=>"删除应用版本", 'msg'=>$this->appmanage->deleteAppEdition()));
					} 
					else 
					{
						$this->load->view('notice', array('title'=>'删除应用版本', 'msg'=>'删除应用版本失败'));		
					}							
				}														
			break;
			// 删除整个应用
			case 'delete_app':
				$app_id = $this->input->post('app_id');
				$command = $this->input->post('command');
				if ($command == 'YES') 
				{											
					$this->load->library("AppManage", array('app_id'=>$app_id));					
					$this->load->view('notice', array('title'=>'删除整个应用', 'msg'=>$this->appmanage->deleteApp()));		
				} 
				else 
				{
					$this->load->view('notice', array('title'=>'删除整个应用', 'msg'=>'删除整个应用失败'));		
				}				
			break;
			
			// 部署到服务器
			case 'deploy_applib_version':
				set_time_limit(0);											
				$applib_id = $this->input->post("applib_id");
				$applibentry_id = $this->input->post("applibentry_id");				
				// Array ( [app_id] => 5 [edition_id] => 8 [id] => [act] => deploy_applib_version [applib_id] => 5 [applibentry_id] => 8 [sftp] => 0 )					
				$sftp = config_item('sftp');
				$params = $sftp[$this->input->post('sftp')];				
				$this->load->library("Deploy", array('applibentry_id'=>$applibentry_id, 'user'=>$params['user'], 'host'=>$params['host'], 'password'=>$params['password'], 'deploy'=> $params['deploy']));									
				$this->load->view('notice', array('title'=>'部署应用', 'msg'=>$this->deploy->deployApp()));		
			break;
			
			default:
				$this->load->view('notice', array('title'=>'操作不存在', 'msg'=>'请重试！'));		
			break;
		}		
	}
	
	// 删除策略
	private function deleteAppLib($applib_id)
	{
		$this->db->where("applib_id", $applib_id);
		$this->db->delete("applibraries_tbl");
		$this->log(self::$_type['DELETE'], "删除一个策略applib_id:{$applib_id}");
	}
	// 删除策略的应用
	private function deleteAppLibVersion($applib_id, $applib)
	{
		//删除applibraryentries_tbl
		$this->db->where("applibentry_id", $applib['applibentry_id']);
		$this->db->delete("applibraryentries_tbl");	
		$this->log(self::$_type['DELETE'], "删除一个策略applibrary_id:{$applib_id}", $applib['app_id']);
		
		//删除applibentryfiles_tbl
		$this->db->where("applib_id", $applib_id);
		$this->db->where("app_id", $applib['app_id']);
		$this->db->where("edition_id", $applib['edition_id']);
		$this->db->delete("applibentryfiles_tbl");	
		$this->log(self::$_type['DELETE'], "删除一个策略applib_id:{$applib_id}对应的应用{$applib['app_id']}版本{$applib['edition_id']}", $applib['app_id']);

	}
	
	private function insertAppLib($applib_id, $app)
	{		
		$files=array();
		// 添加版本
		$insert_libentry = array(
			'applibrary_id'=>$applib_id,
			'app_id'=>$app['app_id'],
			'edition_id'=>$app['edition_id'],
			'applibentry_ver'=>1,//初始策略版本 1 与客户端第一次初始化 
			'edition_ver'=>$app['edition_ver']
		);		
		$this->db->insert("applibraryentries_tbl", $insert_libentry);
		$id = $this->db->insert_id();
		
		$this->log(self::$_type['CREATE'], "为策略添加应用 {$app['app_id']} 版本 {$app['edition_id']}", $app['app_id'], "");
		
		// 添加版本文件
		$data = array();
		$sql = sprintf("SELECT * FROM appfiles_tbl WHERE app_id = '%s' AND edition_id = '%s'", $app['app_id'], $app['edition_id']);
		$query = $this->db->query($sql);
		foreach($query->result_array() as $row) 
		{
			$row['file_original_version'] = $row['file_version'];
			$row['file_version'] = 1;
			$row['applib_id'] = $applib_id;			
			$this->db->insert("applibentryfiles_tbl", $row);
			$files[] = $row['file_name'];
			
			$this->log(self::$_type['CREATE'], "添加应用 {$app['app_id']} 版本 {$app['edition_id']} 文件", $app['app_id'], $row['file_name']);
		}					
		return $files;
	}
	
	// 检查当前应用版本是否有应用文件
	private function hasAppFiles($app)
	{
		$query = $this->db->query(sprintf("SELECT * FROM appfiles_tbl WHERE app_id = '%s' AND edition_id = '%s' LIMIT 1", $app['app_id'], $app['edition_id']));
		$this->log(self::$_type['READ'], "检查应用 {$app['app_id']} 版本 {$app['edition_id']} 是否有文件", $app['app_id']);
		return ($query->num_rows() > 0) ? true : false;		
	}
	
	private function isVersionExists($app_id, $edition_id)
	{
		$query = $this->db->query(sprintf("SELECT * FROM appeditions_tbl WHERE app_id = '%s' AND edition_id = '%s'", $app_id , $edition_id));		
		$this->log(self::$_type['READ'], "检查应用{$app_id}版本{$edition_id}是否存在", $app_id);		
		return ($query->num_rows() > 0) ? true : false ;
	}
	
	public function showForm()
	{ 
		// 整理下各个动作接收的参数及需要获取的数据
		$data = array();
		$view = 'magic_form';
		$this->load->helper('form');		
		
		$act = $this->uri->segment(3);			
		$app_id = $this->uri->segment(4);
		$edition_id = $this->uri->segment(5);
		$id = $this->uri->segment(6);		
		
		$data['title'] = self::$_act[$act];	
		$hidden = array('app_id' => $app_id, 'edition_id' => $edition_id, 'id'=>$id, 'act'=>$act);			
				
		/* tidy up begin */
		switch($act)
		{
			case 'update_app_file':
			case 'delete_app_file':
				// 获取文件的路径信息	
				$file_id = $this->uri->segment(7);		
				$query = $this->db->query("SELECT file_path FROM appfiles_tbl WHERE file_id = $file_id");
				$r = $query->row_array();
				$data['file_path'] = $r['file_path'];
				$hidden['file_id'] = $file_id;	
			break;
			
			case 'add_app_file':
				$file_path = $this->uri->segment(7);
				$data['file_path'] = str_replace('.', '/', trim($file_path));	
			break;
			
			case 'deploy_applib_version':
				$hidden['applib_id'] = $this->uri->segment(4);
				$hidden['applibentry_id'] = $this->uri->segment(5);
				
				$query = $this->db->query("SELECT * FROM applibraryentries_tbl a LEFT JOIN applibraries_tbl b ON a.applibrary_id = b.applib_id WHERE a.applibentry_id = ".$hidden['applibentry_id']);
				$r = $query->row_array();				
				$data['title'] = sprintf("部署策略%s_%d,应用%s[%s]", $r['applib_title'], $r['applibentry_ver'], $r['app_id'], $r['edition_id']);
				// 获得部署的服务器及路径
				$data['sftp'] = config_item("sftp");
				$data['path'] = $this->_path;								
			break;
			
			case 'delete_applib':
			case 'add_applib_version':
			case 'delete_applib_version':
			
				$hidden['applib_id'] = $this->uri->segment(4);
				
				if ($act == 'delete_applib_version') {
					$hidden['applibentry_id'] = $this->uri->segment(5);	
				}				
				
				if ($act == 'add_applib_version')
				{
					unset($hidden['app_id']);
					unset($hidden['edition_id']);
					unset($hidden['id']);
					// 剔除当前策略已经添加的应用
					$sql = "SELECT DISTINCT edition_id, app_id FROM applibentryfiles_tbl WHERE applib_id = %d";
					$query = $this->db->query(sprintf($sql, intval($hidden['applib_id'])));
					$forbid = array();
					if ($query->num_rows()>0)
					{
						foreach($query->result_array() as $row)
						{
							$forbid[] = $row['app_id'].'_'.$row['edition_id'];
						}
					}
					$list = $this->getApp();
					foreach($list as $k => $item)
					{
						$size_ver = count($item['versions']);						
						foreach($item['versions'] as $sk => $version) 
						{
							if (in_array($item['app_id'].'_'.$version['edition_id'], $forbid)) 
							{
								if ($size_ver == 1) 
								{
									unset($list[$k]);
								} 
								else 
								{
									unset($list[$k]['versions'][$sk]);
								}
							}
						}
						
						// 再次确认
						if (isset($list[$k]) && count($list[$k]['versions'])==0) 
						{
							unset($list[$k]);	
						}						
					}			
					$data['list'] = $list;
				}
			break;
		}
		/* tidy up end */				
			
		$this->log(self::$_type['SHOW'], self::$_act[$act], $app_id);
		
		$data['act'] = $act;
		$data['hidden'] = $hidden;		
		$this->load->view('magic_form', $data);
	}
	
	//添加新应用
	public function addApp()
	{
		$data = array();
				
		$this->load->helper(array('form', 'url'));  
		$this->load->library('form_validation');
		$this->form_validation->set_message('required', '<b style="color:red;">*</b> %s必须填写');
		
		if (isset($_POST['submit']))
		{
			$page = $this->input->post('page');
		}
		else
		{
			$page = $this->uri->segment(3);
		}
				
		// 设置条件
		if ($page == 'app')
		{
		    $this->form_validation->set_rules('app_id', '应用标识', 'required');
		    $this->form_validation->set_rules('app_title', '应用标题', 'required');	 
		}
		else
		{
		    $this->form_validation->set_rules('applib_title', '策略标题', 'required');
		}
		$data['hidden'] = array(
			'page'=>$page
		);
	    $data['page'] = $page;	
		$data['title'] = ($page=='app')	? '应用' : '策略';
				 
		if (isset($_POST['submit'])) 
		{
			if ($this->form_validation->run() == FALSE) 
			{
				$this->load->view('add_app', $data);
			}
			else
			{				
				if ($page == 'app')
				{
					//应用					
					$this->load->library("AppManage");
					$this->load->view('notice', array('title'=>'新增应用', 'msg'=>$this->appmanage->insertApp()));
				}
				else
				{
					//策略
					$this->insertStrategy();
					$this->load->view('notice', array('title'=>'新增策略', 'msg'=>'添加策略成功'));
				}				
			}
		} 
		else 
		{
			$this->load->view('add_app', $data);
		}		
	}
	
	private function insertStrategy()
	{
		$applib_title = $this->input->post('applib_title');
		$applib_intro = $this->input->post('applib_intro');
		
		$insert = array(
			'applib_title'=>$applib_title,
			'applib_intro'=>$applib_intro			
		);
		
		$this->db->insert("applibraries_tbl", $insert);		
		$this->log(self::$_type['CREATE'], "创建策略{$applib_title}");
	}
	
	private function insertApp()
	{
		$app_id = $this->input->post('app_id');
		$app_title = $this->input->post('app_title');
		$app_intro = $this->input->post('app_intro');
		
		// 添加应用
		$insert_app = array(
			'app_id'=>$app_id,
			'app_title'=>$app_title,
			'app_intro'=>$app_intro
		);
		$this->db->insert('applications_tbl', $insert_app);		
		$this->log(self::$_type['CREATE'], "创建应用{$app_id}", $app_id);
		// 添加应用版本
		$insert_edition = array(
			'edition_id'=>'standard',
			'app_id'=>$app_id,
			'edition_ver'=>1,
			'edition_intro'=>'nothing',
			'add_time'=> date('Y-m-d H:i:s')	
		);
		$this->db->insert('appeditions_tbl', $insert_edition);	
		$this->log(self::$_type['CREATE'], "创建应用{$app_id}版本standard", $app_id);	
	}
	
	
	// 添加应用版本的文件
	private function insertAppFile($file_path, $file, $path)
	{
		$app_id = $this->input->post('app_id');
		$edition_id = $this->input->post('edition_id');
		$id = $this->input->post('id');
		
		$file_content = file_get_contents($file_path);
		$insert = array(
			'file_title'=>'Nothing',
			'file_name' => $file['name'],
			'file_version'=>1,
			'file_source'=>sprintf("%s/%s/%s", $app_id, $edition_id, $file['name']),
			'file_intro'=>'Nothing',
			'file_content'=>$file_content,
			'app_id'=>$app_id,
			'edition_id'=>$edition_id,
			'file_type'=> strtolower(substr($file['name'], strrpos($file['name'], '.')+1)),
			'file_size'=>$file['size'],
			'file_mime_type'=>$file['type'],
			'file_path' => $path
		);		
		$this->db->insert('appfiles_tbl', $insert);							
		
		// 复制文件到管理目录
		$destination_path = sprintf($this->_path['local_version']."%s/%s/%s",$app_id, $edition_id, $path);		
		// 检查目录是否存在，不存在则建立
		// sff/dff/few/Diablo-3-256-1.ico
		if ($path)
		{
			$dirs = explode("/", $path);
			// 去除文件名
			array_pop($dirs);
			$cdir = sprintf($this->_path['local_version']."%s/%s/", $app_id, $edition_id);
			foreach($dirs as $dir)
			{
				$cdir .= $dir.'/';
				if (! is_dir($cdir)) 
				{
					mkdir($cdir);
				}
			}		
		}		
		copy($file_path, $destination_path);		
		$this->log(self::$_type['CREATE'], "添加应用{$app_id}版本{$edition_id}文件", $app_id, $file['name']);
		$this->updateVersion($id);		
	}
	
	// 覆盖原始文件
	private function updateFile($app_id, $edition_id, $filename, $file_content)
	{
		$path1 = $this->input->post('path1');
		$path1 = ($path1) ? rtrim($path1, '/')."/".$filename : $filename; 
		$file_realpath = sprintf($this->_path['local_version']."%s/%s/%s",$app_id, $edition_id, $path1);
		file_put_contents($file_realpath, $file_content);
	}
		
	/**
	 * 更新版本文件
	 * @param string $file_upload_path 上传文件保存路径
	 * @param array $file 
	 * @param string $path 文件保存路径
	 */
	private function updateAppFile($file_upload_path, $file)
	{
		$file_id = $this->input->post('file_id');
		$id = $this->input->post('id');
		
		$app_id = $this->input->post('app_id');
		$edition_id = $this->input->post('edition_id');
			
		// 检查上传的文件名是否一致
		if (!$this->checkFileName($file_id, $file['name']))
		{
			return array('title'=>'更新文件', 'msg'=>'更新的文件名必须一样。');
		}				
				
		// 更新应用文件的版本号
		$file_content = file_get_contents($file_upload_path);
		$this->db->set('file_content', $file_content);
		$this->db->set('file_size', $file['size']);
		$this->db->set('file_name', $file['name']);
		$this->db->set('file_source', sprintf("%s/%s/%s", $app_id, $edition_id, $file['name']));
		$this->db->set('file_version', 'file_version+1', false);
		$this->db->set('file_type', strtolower(substr($file['name'], strrpos($file['name'], '.')+1)));
		$this->db->set('file_mime_type', $file['type']);
		
		$this->db->where('file_id', $file_id);
		$this->db->update('appfiles_tbl');
				
		// // 更新策略应用文件的版本号
		$this->db->set("file_original_version", "file_original_version+1", false);
		$this->db->where("file_id", $file_id);
		$this->db->update("applibentryfiles_tbl");
		
		unlink($file_upload_path);
		// 覆盖原始文件
		// 删除再添加		
		$query = $this->db->query("SELECT file_path FROM appfiles_tbl WHERE file_id = ".intval($file_id));
		$r = $query->row_array();
		
		$file_delete_path = sprintf($this->_path['local_version']."%s/%s/%s", $app_id, $edition_id, $r['file_path']);		
		unlink($file_delete_path);
		
		$file_save_path = sprintf($this->_path['local_version']."%s/%s/%s", $app_id, $edition_id, $r['file_path']);		
		file_put_contents($file_save_path, $file_content);
		
		$this->log(self::$_type['UPDATE'], "更新应用{$app_id}版本{$edition_id}文件", $app_id, $file['name']);		
		$this->updateVersion($id);
		
		return array('title'=>'更新文件', 'msg'=>'更新成功');
	}
	
	// 获得所有应用
	private function getApp()
	{	
		$appsql = "SELECT * FROM applications_tbl";		
		$query = $this->db->query($appsql);
		$data = array();		
		if ($query->num_rows() > 0)
		{
		   foreach ($query->result_array() as $row)
		   {			
			   $row['add_app_version'] = site_url(sprintf("/app/showForm/%s/%s", 'add_app_version', $row['app_id']));			   
			   $row['versions'] = $this->getAllAppVersions($row['app_id']);
			   $row['delete_app'] = site_url(sprintf("/app/showForm/%s/%s", 'delete_app', $row['app_id']));
			   $data[] = $row;
		   }
		}
		return $data;
	}
	
	private function getAllAppVersions($app_id)
	{
	   $query = $this->db->query(sprintf("SELECT * FROM appeditions_tbl  WHERE app_id = '%s'", $app_id));	   
	   $data = array();
	   if ($query->num_rows() > 0)
	   {
		   foreach ($query->result_array() as $row)
		   {			  						   
			   // LINK: app/version/app/1/yaoxia/standard
			   $this->log(self::$_type['READ'], "读取应用{$row['app_id']}版本{$row['edition_id']}", $row['app_id']);			   
			   $data[] = array(				   
				   'edition_id'=> $row['edition_id'],
				   'edition_ver'=> $row['edition_ver'],
				   'link' => site_url("app/version/app/".$row['id']."/".$row['app_id']."/".$row['edition_id'])				
			   );
		   }
	   }
	   return $data;	   
	}
	
	// 获取所有策略
	private function getStrategy()
	{
		$data = array();
		$query = $this->db->query(sprintf("SELECT * FROM applibraries_tbl"));
		
		if ($query->num_rows() > 0)
		{
			foreach($query->result_array() as $row)
			{
				$this->log(self::$_type['READ'], "读取策略{$row['applib_title']}");
				$row['delete'] = site_url(sprintf("app/showForm/%s/%d", 'delete_applib', $row['applib_id']));
				$row['link'] = site_url(sprintf('app/version/%s/%d', 'applib', $row['applib_id']));
				$data[] = $row;	
			}	
		}
		return $data;
	}
	
	// 更新应用版本
	private function updateVersion($id)
	{
		$this->db->set("edition_ver", "edition_ver+1", false);
		$this->db->where('id', $id);
		$this->db->update('appeditions_tbl');	
		$this->log(self::$_type['UPDATE'], "更新应用版本id:{$id}");		
	}
	// 检查同一个应用版本下文件是否重名
	private function checkFileName($id, $file_name)
	{
		$query = $this->db->query(sprintf("SELECT file_name FROM appfiles_tbl WHERE file_id = %d", $id));
		$r = $query->row_array();
		$this->log(self::$_type['READ'], "检查文件file_id:{$id},file_name:{$file_name}是否重名", '', $file_name);
		return ($r['file_name'] == $file_name) ? true : false;
	}
	
	// 删除一个应用版本文件
	private function deleteAppFile($file_id)
	{
		$query = $this->db->query("SELECT app_id, edition_id, file_path FROM appfiles_tbl WHERE file_id = ".intval($file_id));
		$r = $query->row_array();
		// 删除本地文件
		$filepath = $this->_path['local_version'].$r['app_id']. '/'. $r['edition_id'] . '/' . $r['file_path'];
		unlink($filepath);
				
		$this->db->where("file_id", $file_id);
		$this->db->delete("appfiles_tbl");	
		$this->log(self::$_type['DELETE'], "删除应用版本文件file_id:{$file_id}");	
	}
	
	// 操作记录
	private function log($type, $text, $appid=false, $filename=false)
	{
		$insert = array(
			'am_op_type'=>$type,
			'am_op_time'=>date("Y-m-d H:i:s"),
			'am_op_appid'=>$appid,
			'am_op_filename'=>$filename,
			'am_op_logtext'=>$text
		);
		$this->db->insert("appmanager_operation_history", $insert);
	}
	
	public function listFiles()
	{
		$path = $this->uri->segment(3);
		$base = "./public/version/yaoxia/standard/";
		$dir_path = "";		
		if ($path)
		{			
			if (strpos($path, ".") > 0)
			{
				$dir_path = $base.str_replace('.', '/', $path);					
				$back_link = site_url("app/listFiles/".substr($path, 0, strrpos($path, ".")));
			}
			else
			{	
				$dir_path = $dir_path = $base.$path;				
				$back_link = site_url("app/listFiles");
			}		
		}
		else
		{
			$dir_path = $base;
			$back_link = site_url("app/listFiles");
		}
		
		$this->load->helper('directory');
		
		if (!file_exists($dir_path)) {exit("Directory Not Exists.");}
		
		$files = directory_map($dir_path, 1);		
		$list = array();
		$filenames = array();			
		foreach($files as $file)
		{
			$item = array();
			$item['file'] = $file;
			
			if($file[strlen($file) - 1] == '/')
			{				
				$segment = ($path) ? $path. "." . $file : $file;
				$item['link'] = site_url('/app/listFiles/'. $segment);
				$item['type'] = 'dir';
			}
			else
			{
				$item['type'] = 'file';
				$filenames[] = $file;
			}
			$list[] = $item;
		}				
		$this->load->view('list', array('list'=>$list, 'back'=>$back_link, 'top'=>site_url("app/listFiles")));
	}
	
	
}
